package FIT::Fixture::Factory;

use FIT::Class;
use IO::All -utf8;
use aliased 'FIT::Util::ClassLoader';

my %Loaded = ();

sub make_fixture() {
    my ($class, $table) = @_;
    my $package_name = compute_package_name( $table->fixture_name );
    ClassLoader->load($package_name);
    link_to_fixture_source($table, $package_name);
    return construct_fixture($table, $package_name);
}

sub construct_fixture() {
    my ($table, $package_name) = @_;
	my $fixture;
	eval { $fixture = $package_name->new(table => $table) };
	die "Can't create fixture [$package_name]: $@" if $@;
    return $fixture;
}

sub link_to_fixture_source() {
    my ($table, $package_name) = @_;
    my $context = $table->fit_context;
    return unless $context;

    $package_name   =~ s|::|/|g;
    $package_name  .= '.pm';
    my $absolute    = $INC{$package_name};
    return unless $absolute;

    my $relative = $context->absolute_to_out_dir_relative( $absolute );
    $table->first_cell->set_att(fixture_source => io($relative)->name);
}
 
sub compute_package_name() {
	local $_ = shift;
	die "Can't make fixture with no name" unless defined $_ && /\w/;
    s/ /./g;
	s/\./::/g;
	s/([^:]+)$/Fixture::$1/ if /::/; # add Fixture before last package part
	return $_;
}
